/**
 * Framework for batch testing user profile models
 * Final project by Sergey Nepomnyachiy and Julia Polchin
 * Supervisor: Tsvi Kuflik
 *
 */

package core;

import interfaces.ComponentInterface;
import interfaces.LoggingInterface;
import interfaces.ProgressKeeperInterface;

import java.util.Collection;
import java.util.Vector;

import backend.DummyProgKeeper;
import backend.Stats;

/**
 * Representing experiment group - contains a single users instance and possibly several steps
 * @author Sergey and Julia
 * 
 */
public class Group implements ComponentInterface {
	/**
	 * Users of this experiment group
	 */
	private Users users;
	/**
	 * Contains all that is nested in group - users and steps
	 */
	private Vector<ComponentInterface> stepsAndUsers;
	/**
	 * Reference to progress keeper of choice 
	 */
	private ProgressKeeperInterface pk;

	/**
	 * Reference to logging service
	 */
	private LoggingInterface fs;
	/**
	 * The name of the group (corresponds to directory where it lies)
	 */
	private String name;


	/**
	 * Construct a new group
	 * @param name The name of the group
	 * @param fs The logger of this group
	 */
	public Group(String name, LoggingInterface fs) {
		this.name = name;
		this.fs = fs;
		this.stepsAndUsers = new Vector<ComponentInterface>();
		this.pk = new DummyProgKeeper();
	}

	@Override
	public boolean execute() {
		for (ComponentInterface s : this.stepsAndUsers)
			s.execute();
		Collection<Object> observed = GroupObservedPredictedHolder.getInstance().getObserved();
		Collection<Object> predicted = GroupObservedPredictedHolder.getInstance().getPredicted();
		
		this.fs.write(this.name + ".g","correlation="+Stats.getCorrelation(observed,predicted)+"\n");
		this.fs.write(this.name + ".g","mae="+Stats.getMAE(observed,predicted)+"\n");
		
		StudyObservedPredictedHolder.getInstance().addPredictedObserved(observed,predicted);
		GroupObservedPredictedHolder.getInstance().clear();
		return true;
	}

	@Override
	public void setFs(LoggingInterface fs) {
		this.fs = fs;
	}

	/**
	 * Setting the users of this group
	 * @param u Instance of users class
	 */
	public void setUsers(Users u) {
		if (this.users == null)
			this.users = u;
		this.stepsAndUsers.add(u);
	}


	/**
	 * Getter for group name
	 * 
	 * @return the name of the group
	 */
	public String getName() {
		return this.name;
	}

	/**
	 * Adding pre or post processing steps for the group
	 * @param stp Instance of step class
	 */
	public void addStep(Step stp) {
		this.stepsAndUsers.add(stp);
	}

	@Override
	public void setProgresser(ProgressKeeperInterface pk) {
		this.pk = pk;
		this.pk.getMax();
		for (ComponentInterface s : this.stepsAndUsers)
			s.setProgresser(pk);
		
	}

}